package com.exm.collectcodenew.juc.locksuport;

import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.LockSupport;
/*
*先进先出的锁，也就是只有队列的首元素可以获取锁。
 */
public class FIFOMutex {
    private final AtomicBoolean locked = new AtomicBoolean(false);
    private final Queue<Thread> waiters = new ConcurrentLinkedQueue<Thread>();

    public void lock() {
        boolean wasinterrupted = false;
        Thread current = Thread.currentThread();
        waiters.add(current);
        // 只有队首的线程可以获取锁（ 1 )
        while (waiters.peek() != current || locked.compareAndSet(false, true)) {
            LockSupport.park(this);
            if (Thread.interrupted()) //( 2 )
                wasinterrupted = true;
        }
        waiters.remove();
        if (wasinterrupted) // ( 3)
            current.interrupt();
    }

    public void unlock() {
        locked.set(false);
        LockSupport.unpark(waiters.peek());
    }
}